#pragma once

#include <vector>
#include <string>
#include <map>

#include "TreeNode.h"
#include "RelationshipArgumentType.h"
#include "PatternEntry.h"

/*!
PatternTable stores information about the Patterns being queried.
The information contained in it are of the following format:
[the selected synonym - argument 1 - argument 2 - argument 3]
*/
class PatternTable {
	private:
		std::vector<PatternEntry> mPatternEntryVector;

		/// Creates a PatternEntry data structure and inserts it into the table.
		void insertNewPatternEntry(PatternType patternType, const std::string& synonym, 
			const std::string& arg1, TreeNode* arg1ExprRoot, bool perfectMatchNeeded1, RelationshipArgumentType arg1Type,
			const std::string& arg2, TreeNode* arg2ExprRoot, bool perfectMatchNeeded2, RelationshipArgumentType arg2Type,
			const std::string& arg3, TreeNode* arg3ExprRoot, bool perfectMatchNeeded3, RelationshipArgumentType arg3Type);
public:
		PatternTable(void);
		~PatternTable(void);

		/*!
		If the synonym is NOT empty, this function adds the synonym and its corresponding pattern
		to the table. Empty string arguments are allowed.
		If the synonym is empty, does nothing and returns false.
		e.g. addPattern("a", "x", true, rootNode for "x+y+z", true, NULL, false)
		*/
		bool addPattern(PatternType patternType, const std::string& synonym, 
			const std::string& arg1, bool perfectMatchNeeded1,
			TreeNode* arg2Expr, bool perfectMatchNeeded2,
			TreeNode* arg3Expr, bool perfectMatchNeeded3);
		/*!
		Overload of the basic addPattern function, this function is used 
		when the first argument in the pattern is actually a synonym.
		e.g. addPattern("a", "v", true, SYNONYM_VARIABLE, rootNode for "x+y+z", true, NULL, false)
		*/
		bool addPattern(PatternType patternType, const std::string& synonym, 
			const std::string& arg1, bool perfectMatchNeeded1, RelationshipArgumentType synType1,
			TreeNode* arg2Expr, bool perfectMatchNeeded2,
			TreeNode* arg3Expr, bool perfectMatchNeeded3);

		/// Get the number of pattern entries currently in the table.
		int getNumberOfEntries(void);

		/// Gets the pattern entry at the given index.
		PatternEntry getPatternEntryAtIndex(int index);

		bool replaceSynonym(const std::string& s1, const std::string& s2);

};

